using System;
using Microsoft.SPOT;
using OST.Shared.SharedTypes;

namespace OST.Shared.Interfaces
{
    /// <summary>
    /// abstract interface motor
    /// </summary>
    public interface IMotor : INotifyPropertyChanged
    {
        /// <summary>
        /// check flag for initialization-state
        /// </summary>
        bool IsInitialized { get; }

        /// <summary>
        /// re-)start initialization
        /// </summary>
        void Initialize();

        /// <summary>
        /// calibrates the concrete motor-implementation-instance
        /// </summary>
        void Calibrate();

        /// <summary>
        /// actual driving direction
        /// </summary>
        enumMotorDrivingDirection DrivingDirection { get; }

        /// <summary>
        /// current motor-position, in mm
        /// </summary>
        int Position { get; }

        /// <summary>
        /// flag, checked, if motor is actual in motion
        /// </summary>
        bool Driving { get;  }

        /// <summary>
        /// motor-configuration
        /// </summary>
        MotorConfiguration MotorConfig { get; set; }

        /// <summary>
        /// frame-configuration
        /// </summary>
        FrameConfiguration FrameConfig { get; set; }

        /// <summary>
        /// manual-direction control for moving down
        /// </summary>
        void MoveDown();

        /// <summary>
        /// manual-direction control for moving up
        /// </summary>
        void MoveUp();

        /// <summary>
        /// stops the motor immediately
        /// </summary>
        void Stop();

        /// <summary>
        /// starts an async position-request for a specified position
        /// </summary>
        /// <remarks>just one request is manageable</remarks>
        /// <param name="motorTarget">target position, in mm</param>
        void Move2MotorPositionAsync(int motorTarget);

        /// <summary>
        /// result-callback for async-position-request 'Move2MotorPositionAsync'
        /// </summary>
        event delMotorTargetReached MotorTargetReached;
    }

    /// <summary>
    /// Event Handler (delegate) for motor position reached
    /// </summary>
    /// <param name="motorCalculatedPosition">real position</param>
    /// <param name="motorTargetPosition">desired position</param>
    /// <param name="timedOut">flag if position is timed-out</param>
    public delegate void delMotorTargetReached(int motorCalculatedPosition, int motorTargetPosition, bool timedOut);
}
